import React, { useState, useEffect, useRef } from "react";
import Chart from "chart.js/auto";
import "./styles.css";

const App1 = () => {
  const chartContainer1 = useRef(null);
  const chartContainer2 = useRef(null);
  const [isGeneratingData, setIsGeneratingData] = useState(false);
  const [dataInterval, setDataInterval] = useState(null);
  const [userCount, setUserCount] = useState(10);
  const [lowerBound, setLowerBound] = useState(0);
  const [upperBound, setUpperBound] = useState(3);
  const [ldpParam, setLdpParam] = useState(5);
  const [currentTimestamp, setCurrentTimestamp] = useState(0);

  const chartRef1 = useRef(null);
  const chartRef2 = useRef(null);

  const startDataGeneration = () => {
    if (isGeneratingData) return;

    setIsGeneratingData(true);

    setDataInterval(setInterval(generateData, 1000));
  };

  const stopDataGeneration = () => {
    setIsGeneratingData(false);

    clearInterval(dataInterval);
  };

  const generateData = () => {
    const dataVector = Array.from({ length: userCount }, () =>
      Math.floor(Math.random() * (upperBound - lowerBound + 1) + lowerBound)
    );

    const perturbedDataVector = [...dataVector];

    setCurrentTimestamp((prevTimestamp) => prevTimestamp + 1);

    // Update the datasets based on the generated data
    updateChart(chartRef1, dataVector);

    // Update the datasets based on the perturbed data
    updateChart(chartRef2, perturbedDataVector);
  };

  const updateChart = (chartRef, dataVector) => {
    const labels = Array(upperBound - lowerBound + 1)
      .fill()
      .map((_, index) => index + lowerBound);

    const dataCounts = Array(labels.length).fill(0);

    dataVector.forEach((val) => {
      dataCounts[val - lowerBound]++;
    });

    chartRef.current.data.labels = labels;
    chartRef.current.data.datasets[0].data = dataCounts;
    chartRef.current.update();
  };

  useEffect(() => {
    // Initialize the charts
    const ctx1 = chartContainer1.current?.getContext("2d");
    const ctx2 = chartContainer2.current?.getContext("2d");

    if (!chartRef1.current) {
      chartRef1.current = new Chart(ctx1, {
        type: "bar",
        data: {
          labels: [],
          datasets: [
            {
              label: "Input Data Distribution",
              data: [],
              borderColor: "rgba(75,192,192,1)",
              backgroundColor: "blue",
              fill: false,
            },
          ],
        },
        options: {
          scales: {
            x: {
              type: "linear",
              position: "bottom",
            },
            y: {
              beginAtZero: true,
            },
          },
        },
      });
    }

    if (!chartRef2.current) {
      chartRef2.current = new Chart(ctx2, {
        type: "bar",
        data: {
          labels: [],
          datasets: [
            {
              label: "Perturbed Data Distribution",
              data: [],
              borderColor: "rgba(192,75,192,1)",
              backgroundColor: "red",
              fill: false,
            },
          ],
        },
        options: {
          scales: {
            x: {
              type: "linear",
              position: "bottom",
            },
            y: {
              beginAtZero: true,
            },
          },
        },
      });
    }

    return () => {
      // Cleanup when the component unmounts
      clearInterval(dataInterval);
    };
  }, [dataInterval]);

  return (
    <div>
      <mid>
        <h1>Local Differential Privacy</h1>

        <label htmlFor="userCount">Number of Users:</label>
        <div class="center">
          <input
            type="number"
            id="userCount"
            defaultValue={userCount}
            onChange={(e) => setUserCount(parseInt(e.target.value, 10))}
          />
        </div>

        <label htmlFor="lowerBound">Data Lower Bound:</label>
        <div class="center">
          <input
            type="number"
            id="lowerBound"
            step="1"
            defaultValue={lowerBound}
            onChange={(e) => setLowerBound(parseInt(e.target.value, 10))}
          />
        </div>

        <label htmlFor="upperBound">Data Upper Bound:</label>
        <div class="center">
          <input
            type="number"
            id="upperBound"
            step="1"
            defaultValue={upperBound}
            onChange={(e) => setUpperBound(parseInt(e.target.value, 10))}
          />
        </div>

        <label htmlFor="ldpParam">LDP Algorithm Parameter:</label>
        <div class="center">
          <input
            type="number"
            id="ldpParam"
            step="1"
            defaultValue={ldpParam}
            onChange={(e) => setLdpParam(parseInt(e.target.value, 10))}
          />
        </div>
        <br />
        <div class="center">
          <button onClick={startDataGeneration}>Start Data Generation</button>
        </div>
        <div class="center">
          <button onClick={stopDataGeneration}>Stop Data Generation</button>
        </div>
      </mid>

      <canvas
        ref={chartContainer1}
        id="chart-container-1"
        width="800"
        height="400"
      ></canvas>
      <canvas
        ref={chartContainer2}
        id="chart-container-2"
        width="800"
        height="400"
      ></canvas>
      <br />
      <br />
    </div>
  );
};

export default App1;
